package com.liqw.core;

import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 并发直播课管理器（处理多课程并发观看）
 */
@Slf4j
public class LiveCourseConcurrentManager {
    private final WebDriver driver;
    private final int maxConcurrentCourses;
    private final ExecutorService executorService;
    private final LiveCourseManager liveCourseManager;

    /**
     * 构造函数
     */
    public LiveCourseConcurrentManager(WebDriver driver, int maxConcurrentCourses) {
        this.driver = driver;
        this.maxConcurrentCourses = maxConcurrentCourses;
        this.executorService = Executors.newFixedThreadPool(maxConcurrentCourses);
        this.liveCourseManager = new LiveCourseManager(driver);
    }

    /**
     * 并发播放已录制的直播课
     */
    public void playRecordedLiveCoursesConcurrently() {
        // 保存原始窗口句柄
        AtomicReference<String> mainWindowRef = new AtomicReference<>(driver.getWindowHandle());

        // 使用Semaphore控制并发数量
        Semaphore semaphore = new Semaphore(5);

        try {
            // 导航到直播课页面
            boolean navigateSuccess = liveCourseManager.navigateToLiveCoursesPage();
            if (!navigateSuccess) {
                log.error("无法导航到直播课页面");
                return;
            }

            // 查找可重播的课程
            List<WebElement> coursesToPlay = findRecordedCourses();
            if (coursesToPlay.isEmpty()) {
                log.info("未找到可重播的直播课");
                return;
            }

            log.info("找到 {} 个可重播的直播课，将使用最大并发数 {} 进行播放", 
                    coursesToPlay.size(), maxConcurrentCourses);

            // 提交所有任务
            List<Future<Boolean>> futures = new ArrayList<>();
            for (WebElement webElement : coursesToPlay) {
                LiveCourseTask task = new LiveCourseTask(
                        driver,
                        webElement,
                        semaphore,
                        mainWindowRef,
                        liveCourseManager
                );
                futures.add(executorService.submit(task));
            }

            // 等待所有任务完成
            waitForAllTasksToComplete(futures);
            
        } catch (Exception e) {
            log.error("并发播放课程时发生异常", e);
        } finally {
            // 关闭线程池
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 查找可重播的课程
     */
    private List<WebElement> findRecordedCourses() {
        List<WebElement> courses = new ArrayList<>();
        try {
            // 等待直播课列表加载
            WebDriverUtils.waitForElementVisible(driver,
                    By.cssSelector(SelectorConstants.CSS_LIVE_COURSE_LIST_CONTAINER));

            // 获取所有直播课项
            List<WebElement> liveCourseItems = driver.findElements(
                    By.cssSelector(SelectorConstants.CSS_LIVE_COURSE_ITEM));

            log.info("共发现 {} 个直播课", liveCourseItems.size());

            for (WebElement courseItem : liveCourseItems) {
                try {
                    // 获取直播课信息
                    String courseName = liveCourseManager.getCourseTitle(courseItem);
                    String courseStatus = liveCourseManager.getCourseStatus(courseItem);

                    log.info("直播课名称: {}, 状态: {}", courseName, courseStatus);

                    // 只处理已录制（可重播）的课程
                    if (liveCourseManager.isRecordedCourse(courseStatus)) {
                        log.info("找到可重播的录制课程: {}", courseName);
                        courses.add(courseItem);
                    } else {
                        log.info("课程 {} 不可重播或未录制，跳过", courseName);
                    }
                } catch (Exception e) {
                    log.error("处理直播课信息时发生异常", e);
                }
            }
        } catch (Exception e) {
            log.error("查找直播课时发生异常", e);
        }
        return courses;
    }

    /**
     * 等待所有任务完成
     */
    private void waitForAllTasksToComplete(List<Future<Boolean>> futures) {
        int completedTasks = 0;
        int totalTasks = futures.size();
        
        while (completedTasks < totalTasks) {
            completedTasks = 0;
            for (int i = 0; i < futures.size(); i++) {
                Future<Boolean> future = futures.get(i);
                if (future.isDone()) {
                    completedTasks++;
                    try {
                        Boolean result = future.get();
                        log.info("任务 {} 已完成，结果: {}", i + 1, result);
                    } catch (Exception e) {
                        log.error("获取任务结果时发生异常", e);
                    }
                }
            }
            
            if (completedTasks < totalTasks) {
                try {
                    Thread.sleep(5000); // 每5秒检查一次
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
    }

    /**
     * 清理窗口资源
     */
    private void cleanUpWindows(String originalHandle) {
        try {
            // 获取所有窗口句柄
            Set<String> handles = driver.getWindowHandles();
            
            // 切换到原始窗口
            driver.switchTo().window(originalHandle);
            
            // 关闭所有其他窗口
            for (String handle : handles) {
                if (!handle.equals(originalHandle)) {
                    try {
                        driver.switchTo().window(handle).close();
                    } catch (Exception e) {
                        log.warn("关闭窗口失败: {}", e.getMessage());
                    }
                }
            }
            
            // 确保最后回到原始窗口
            driver.switchTo().window(originalHandle);
        } catch (Exception e) {
            log.error("清理窗口资源时发生异常", e);
        }
    }
}